﻿namespace DYH.Extensions.CAD.Tools.Cad;

/// <summary>
/// 多段线工具类
/// </summary>
public static class PolylineTool
{
    /// <summary>
    /// 修复多段线，删除重复点和共线点。
    /// </summary>
    /// <param name="pl">需要修复的多段线对象。</param>
    /// <param name="tol">容差值，用于判断点是否共线，默认值为1e-6。</param>
    public static void Repair(this Polyline pl, double tol = 1e-6)
    {
        // 删除重复点（重合点）
        for (var i = pl.NumberOfVertices - 1; i >= 0; i--)
        {
            if (pl.GetSegmentType(i) == SegmentType.Coincident)
            {
                pl.RemoveVertexAt(i);
            }
        }

        // 如果顶点数小于3，则无需进一步处理
        if (pl.NumberOfVertices < 3)
            return;

        // 遍历多段线的每个顶点，删除共线点
        for (var j = pl.NumberOfVertices - 1; j >= 0; j--)
        {
            var i = (j + pl.NumberOfVertices - 1) % pl.NumberOfVertices;
            var k = (j + 1) % pl.NumberOfVertices;

            // 仅处理线段类型为直线的顶点
            if (pl.GetSegmentType(i) != SegmentType.Line ||
                pl.GetSegmentType(j) != SegmentType.Line)
                continue;

            // 获取当前顶点及其前后两个顶点的坐标
            var pt1 = pl.GetPoint3dAt(i);
            var pt2 = pl.GetPoint3dAt(j);
            var pt3 = pl.GetPoint3dAt(k);

            // 计算向量并判断是否共线
            var v12 = pt1.GetVectorTo(pt2);
            var v13 = pt1.GetVectorTo(pt3);
            var per13 = v13.GetPerpendicularVector().GetNormal();

            // 如果点共线，则删除当前顶点
            if (Math.Abs(per13.DotProduct(v12)) < tol)
                pl.RemoveVertexAt(j);
        }
    }

    /// <summary>
    /// 向多段线添加一个新顶点。
    /// </summary>
    /// <param name="pl">需要添加顶点的多段线对象。</param>
    /// <param name="pt">要添加的顶点坐标。</param>
    public static void Add(this Polyline pl, Point3d pt)
    {
        pl.AddVertexAt(pl.NumberOfVertices, pt.Point2d(), 0, 0, 0);
    }
}
